/**
 * 
 */
package edu.gatech.oad.mule.model;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;

import edu.gatech.oad.mule.Game;
import edu.gatech.oad.mule.input.interfaces.InputListener;
import edu.gatech.oad.mule.model.GameStateMachine.GameState;
import edu.gatech.oad.mule.view.interfaces.RenderableGameDriver;

/**
 * Represents a phase of a game of Mule. Phases will need to have access to the
 * current game data and will need to be able to handle user input. A boolean
 * value is used to determine whether the phase should be handling data or not.
 * 
 * @author Dale Avery
 * 
 */
abstract class Phase implements InputListener, RenderableGameDriver, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3886593691263224295L;
	
	protected Game game;
	protected boolean active;
	private Vector<PhaseListener> _listeners;

	/**
	 * Constructs a new Phase.
	 * 
	 * @param game
	 *            Object used to obtain relevant information for phase.
	 */
	public Phase(Game game) {
		this.game = game;
		active = false;
	}

	/**
	 * Add's a given PhaseListener to the list of listeners who will be
	 * notified when a phase event occurs.
	 * 
	 * @param listener
	 *            The listener to be added to the list.
	 */
	public final void addActionListener(PhaseListener listener) {
		if (_listeners == null)
			_listeners = new Vector<PhaseListener>();

		_listeners.addElement(listener);
	}

	/**
	 * Sends notification to all listeners that a phase has ended.
	 */
	protected final void endPhase() {
		if (_listeners != null && !_listeners.isEmpty()) {
			Enumeration<PhaseListener> listeners = _listeners.elements();
			while (listeners.hasMoreElements()) {
				PhaseListener listener = (PhaseListener) listeners
						.nextElement();
				listener.endPhaseHandler(this);
			}
		}
	}
	
	/**
	 * @return True if the state is running, false otherwise.
	 */
	public boolean isActive() {
		return active;
	}
	
	/**
	 * Begins the phase.
	 */
	public abstract void start();
	
	/**
	 * Stops the phase.
	 */
	public abstract void stop();
	
	/**
	 * Resets the phase.
	 */
	public abstract void reset();
	
	/**
	 * @return The state that corresponds to this phase
	 */
	public abstract GameState getCorrespondingState();
}
